<template>
  <a-collapse expandIconPosition="right">
    <a-collapse-panel header="队列" :force-render="true">
      <a-collapse expandIconPosition="right" class="!mb-20px">
        <a-collapse-panel
          v-for="item in props.mode == 'add' ? queueList : editList"
          :header="item.formValue.name"
          :key="item.id"
          :force-render="true"
        >
          <template #extra>
            <a-button
              @click.stop="handleDelete(item.id)"
              type="text"
              size="small"
              :preIcon="ICON.DELETE"
            />
          </template>
          <BasicForm @register="item.Form[0]">
            <template #name="{ model, field }">
              <Input
                v-model:value="model[field]"
                @change="(e) => handleChangeName(item.id, e.target.value)"
              />
            </template>
            <template #submitSetting>
              <a-collapse expandIconPosition="right">
                <a-collapse-panel header="提交设置" :force-render="true">
                  <BasicForm @register="item.slotFormInstance.submitSettingForm[0]" />
                </a-collapse-panel>
              </a-collapse>
            </template>
            <template #retrySetting>
              <a-collapse expandIconPosition="right">
                <a-collapse-panel header="重试处理设置" :force-render="true">
                  <BasicForm @register="item.slotFormInstance.retrySettingForm[0]" />
                </a-collapse-panel>
              </a-collapse>
            </template>
            <template #pollingSetting>
              <a-collapse expandIconPosition="right">
                <a-collapse-panel header="轮询设置" :force-render="true">
                  <BasicForm @register="item.slotFormInstance.pollingSettingForm[0]" />
                </a-collapse-panel>
              </a-collapse>
            </template>
          </BasicForm>
        </a-collapse-panel>
      </a-collapse>
      <a-button @click="handleAdd">添加</a-button>
    </a-collapse-panel>
  </a-collapse>
</template>

<script lang="ts" setup>
  import { Collapse as ACollapse, CollapsePanel as ACollapsePanel, Input } from 'ant-design-vue';
  import { ICON } from '/@/enums/iconEnum';
  import { ref, watch, onMounted, nextTick } from 'vue';
  import { guid, ListType, formList, baseFormConfig, generateFormInsFun } from './queue.data';
  import { BasicForm, useForm, FormProps } from '/@/components/Form';
  import { schemas, editSchemas } from './components/queueForm.data';
  import { cloneDeep } from 'lodash-es';
  import { useMessage } from '/@/hooks/web/useMessage';

  const emits = defineEmits(['collectQueueData']);
  const props = defineProps({
    okFlag: { type: Boolean, default: false },
    editQueue: { type: Array, default: () => [] },
    mode: { type: String, default: '' },
  });
  const { createMessage } = useMessage();

  const flag = ref<boolean>(false);
  const queueList = ref<Array<ListType>>(cloneDeep(formList));
  const editList = ref<Array<ListType>>([]);
  watch(
    () => props.okFlag,
    async (nVal) => {
      flag.value = nVal;
      handleMerge();
    },
  );
  watch(
    () => props.editQueue,
    (nVal) => {
      if (nVal && nVal.length > 0) {
        nVal.forEach((item: any) => {
          editSchemas.forEach((element) => {
            switch (element.field) {
              case 'customProperties':
                element.defaultValue = item.additionalInfo.customProperties;
                break;
              case 'description':
                element.defaultValue = item.additionalInfo.description;
                break;
            }
          });
          editList.value.push({
            id: guid(),
            Form: useForm(
              Object.assign(
                {
                  schemas: [
                    {
                      field: 'name',
                      component: 'Input',
                      label: '名称',
                      colProps: {
                        span: 24,
                      },
                      slot: 'name',
                      required: true,
                      defaultValue: item.name,
                    },
                    ...editSchemas,
                  ],
                },
                baseFormConfig,
              ) as FormProps,
            ),
            slotFormInstance: generateFormInsFun(),
            formValue: {
              name: item.name,
              submitSetting: {
                type: item.submitStrategy.type,
                batchSize: item.submitStrategy.batchSize,
              },
              retrySetting: {
                processType: item.processingStrategy.type,
                retries: item.processingStrategy.retries,
                failurePercentage: item.processingStrategy.failurePercentage,
                pauseBetweenRetries: item.processingStrategy.pauseBetweenRetries,
                maxPauseBetweenRetries: item.processingStrategy.maxPauseBetweenRetries,
              },
              pollingSetting: {
                pollInterval: item.pollInterval,
                partitions: item.partitions,
                consumerPerPartition: item.consumerPerPartition,
                packProcessingTimeout: item.packProcessingTimeout,
              },
            },
          });
        });
      } else {
        editList.value = cloneDeep(formList);
      }
    },
    {
      immediate: true,
      deep: true,
    },
  );

  function handleAdd() {
    let obj = {
      id: guid(),
      Form: useForm(
        Object.assign(
          {
            schemas: [...schemas],
          },
          baseFormConfig,
        ) as FormProps,
      ),
      slotFormInstance: generateFormInsFun(),
      formValue: {
        name: '',
        submitSetting: {},
        retrySetting: {},
        pollingSetting: {},
      },
    };
    if (props.mode == 'add') {
      queueList.value.push(obj);
    } else if (props.mode == 'edit') {
      editList.value.push(obj);
    }
  }
  function handleDelete(id: string) {
    queueList.value = queueList.value.filter((item) => item.id !== id);
    editList.value = editList.value.filter((item) => item.id !== id);
  }
  async function handleMerge() {
    let list: any[] = [];
    let arr: any[] = [];
    try {
      for (const item of props.mode == 'add' ? queueList.value : editList.value) {
        const { validate } = item.Form[1];
        const { validate: validateSetting } = item.slotFormInstance.submitSettingForm[1];
        const { validate: validateRetry } = item.slotFormInstance.retrySettingForm[1];
        const { validate: validatePolling } = item.slotFormInstance.pollingSettingForm[1];
        const { name, customProperties, description } = await validate();
        const submitSetting = await validateSetting();
        const retrySetting = await validateRetry();
        const pollingSetting = await validatePolling();
        const { type, batchSize } = submitSetting;
        const {
          failurePercentage,
          maxPauseBetweenRetries,
          pauseBetweenRetries,
          processType,
          retries,
        } = retrySetting;
        const { pollInterval, partitions, packProcessingTimeout, consumerPerPartition } =
          pollingSetting;
        let topicName = '';
        arr.push({
          id: item.id,
          consumerPerPartition,
          packProcessingTimeout,
          partitions,
          pollInterval,
          submitStrategy: {
            type,
            batchSize,
          },
          processingStrategy: {
            failurePercentage,
            maxPauseBetweenRetries,
            pauseBetweenRetries,
            retries,
            type: processType,
          },
        });
        switch (name) {
          case 'Main':
            topicName = 'main';
            break;
          case 'HighPriority':
            topicName = 'hp';
            break;
          case 'SequentialByOriginator':
            topicName = 'sq';
            break;
          default:
            topicName = name;
            break;
        }
        list.push({
          name: name,
          additionalInfo: {
            customProperties,
            description,
          },
          topic: 'tb_rule_engine.' + topicName,
        });
      }
      let queueConfiguration: any[] = [];
      list.forEach((item, index) => {
        queueConfiguration.push({
          ...item,
          ...arr[index],
        });
      });
      emits('collectQueueData', 'success', queueConfiguration);
    } catch (error) {
      createMessage.warning('表单填写有误！');
      emits('collectQueueData', 'fail');
    }
  }

  function handleChangeName(id: string, value: string | undefined) {
    (props.mode == 'add' ? queueList : editList).value.some((item) => {
      return item.id === id ? (item.formValue.name = value) : false;
    });
  }

  onMounted(() => {
    if (props.mode == 'add') {
      nextTick(() => {
        queueList.value.forEach((item) => {
          const { setFieldsValue: setSubmitSetting } = item.slotFormInstance.submitSettingForm[1];
          const { setFieldsValue: setRetrySetting } = item.slotFormInstance.retrySettingForm[1];
          const { setFieldsValue: setPolling } = item.slotFormInstance.pollingSettingForm[1];
          setSubmitSetting({
            ...item.formValue.submitSetting,
          });
          setRetrySetting({
            ...item.formValue.retrySetting,
          });
          setPolling({
            ...item.formValue.pollingSetting,
          });
        });
      });
    } else if (props.mode == 'edit') {
      nextTick(() => {
        editList.value.forEach((item) => {
          const { setFieldsValue: setSubmitSetting } = item.slotFormInstance.submitSettingForm[1];
          const { setFieldsValue: setRetrySetting } = item.slotFormInstance.retrySettingForm[1];
          const { setFieldsValue: setPolling } = item.slotFormInstance.pollingSettingForm[1];
          setSubmitSetting({
            ...item.formValue.submitSetting,
          });
          setRetrySetting({
            ...item.formValue.retrySetting,
          });
          setPolling({
            ...item.formValue.pollingSetting,
          });
        });
      });
    }
  });
</script>
